# frozen_string_literal: true

module Gitlab
  module VulnerabilityScanning
    class SecurityReportBuilder
      include Gitlab::Utils::StrongMemoize

      # We don't have a schema version set because there is no JSON to validate.
      SECURITY_REPORT_VERSION = "0.0.0"

      attr_reader :report

      def initialize(report_type:, project:, pipeline:, sbom:)
        @report_type = report_type
        @project = project
        @pipeline = pipeline
        @sbom = sbom
        @report = ::Gitlab::Ci::Reports::Security::Report.new(report_type, pipeline, Time.zone.now)
        report.version = SECURITY_REPORT_VERSION
        report.add_scanner(scanner)
      end

      # Add advisories affecting a component to the security report.
      #
      # @param advisories [Array<Gitlab::VulnerabilityScanning::Advisory>]
      def add_advisories(advisories)
        advisories.each { |a| add_advisory(a) }
      end

      private

      attr_reader :report_type, :project, :pipeline, :sbom

      def scanner
        VulnerabilityScanning::SecurityScanner.fabricate
      end
      strong_memoize_attr :scanner

      def add_advisory(advisory)
        builder = case report_type
                  when "dependency_scanning"
                    DependencyScanning::FindingBuilder.new(project: project, pipeline: pipeline,
                      sbom_source: sbom.source, scanner: scanner, advisory: advisory)
                  end

        return unless builder

        begin
          finding = builder.finding
          report.add_finding(finding)
          finding.identifiers.each { |ident| report.add_identifier(ident) }
        rescue DependencyScanning::FindingBuilder::MissingPropertiesError => error
          report.add_error('MissingPropertiesError', error.message)
        end
      end
    end
  end
end
